package pr.lanmu.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.update.UpdateChain;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pr.lanmu.annotation.CustomLog;
import pr.lanmu.common.mapper.RoleMapper;
import pr.lanmu.common.mapper.RoleMenuMapper;
import pr.lanmu.common.mapper.RoleModuleMapper;
import pr.lanmu.common.po.Role;
import pr.lanmu.common.po.RoleMenu;
import pr.lanmu.common.po.RoleModule;
import pr.lanmu.config.util.ConvertUtil;
import pr.lanmu.config.util.PageUtil;
import pr.lanmu.config.util.Res;
import pr.lanmu.config.web.CustomException;
import pr.lanmu.config.web.CustomPageInfo;
import pr.lanmu.controller.request.RoleReq;
import pr.lanmu.controller.response.RoleRes;
import pr.lanmu.dao.RoleDao;

import java.util.List;
import java.util.stream.Collectors;

@Service
@CustomLog
@SuppressWarnings("all")
public class RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private RoleModuleMapper roleModuleMapper;

    public Res<CustomPageInfo<RoleRes.list>> list(RoleReq.list param) {
        PageHelper.startPage(param.getPageIndex(), param.getPageSize());
        PageInfo<RoleRes.list> page = new PageInfo<>(roleDao.list());
        return Res.success(PageUtil.getPageInfo(page));
    }

    public Res<?> save(RoleReq.save param) {
        QueryChain.of(Role.class)
                .where(Role::getName).eq(param.getName())
                .oneOpt()
                .ifPresent(Role -> {
                    if (!Role.getId()
                            .equals(param.getId())) {
                        throw new CustomException("角色名已存在");
                    }
                });
        roleMapper.insertOrUpdate(ConvertUtil.copy(param, new Role()), true);
        return Res.success();
    }

    @Transactional(rollbackFor = Exception.class)
    public Res<?> del(RoleReq.del param) {
        roleMapper.deleteById(param.getId());
        //移除是此角色的用户的此角色
        roleDao.delUserRole(param.getId());
        return Res.success();
    }

    public Res<List<Role>> all(RoleReq.all param) {
        return Res.success(roleMapper.selectAll());
    }

    @Transactional(rollbackFor = Exception.class)
    public Res<?> setMenu(RoleReq.setMenu param) {
        //删除角色菜单
        UpdateChain.of(RoleMenu.class)
                .where(RoleMenu::getRoleId).eq(param.getId())
                .remove();
        //添加角色菜单
        List<RoleMenu> list = param.getMenu()
                .parallelStream()
                .map(menuId -> new RoleMenu().setRoleId(param.getId())
                        .setMenuId(menuId))
                .collect(Collectors.toList());
        if (list.size() > 0) roleMenuMapper.insertBatch(list);
        return Res.success();
    }

    @Transactional(rollbackFor = Exception.class)
    public Res<?> setModule(RoleReq.setModule param) {
        //删除角色模块
        UpdateChain.of(RoleModule.class)
                .where(RoleModule::getRoleId).eq(param.getId())
                .remove();
        //添加角色菜单
        List<RoleModule> list = param.getModule()
                .parallelStream()
                .map(menuId -> new RoleModule().setRoleId(param.getId())
                        .setModuleId(menuId))
                .collect(Collectors.toList());
        if (list.size() > 0) roleModuleMapper.insertBatch(list);
        return Res.success();
    }
}